package com.denghq.projectbuilder.component.aif.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.denghq.projectbuilder.component.aif.ApiConfig;
import com.denghq.projectbuilder.component.aif.PermissonConfig;
import com.denghq.projectbuilder.component.aif.Scheme;
import com.denghq.projectbuilder.component.aif.model.DepartmentModel;
import com.denghq.projectbuilder.component.aif.model.ExceptionModel;
import com.denghq.projectbuilder.component.aif.model.PermissionDetailModel;
import com.denghq.projectbuilder.component.aif.model.ResultInfoModel;
import com.denghq.projectbuilder.component.aif.model.UserModel;
import com.denghq.projectbuilder.component.aif.model.UserRightViewModel;
import com.denghq.projectbuilder.component.aif.pojo.PermissonDepartmentInfo;
import com.denghq.projectbuilder.component.aif.service.MicroServiceCaller;
import com.denghq.projectbuilder.component.aif.service.SysUserService;
import com.denghq.projectbuilder.component.aif.utils.UserContextHolder;
import com.denghq.projectbuilder.common.CodeMsg;
import com.denghq.projectbuilder.common.cache.LocalCache;
import com.denghq.projectbuilder.common.exception.BussinessException;
import com.google.common.collect.Maps;

@Service("sysUserInfoService")
public class SysUserServiceImpl implements SysUserService {

	private static LocalCache cache = LocalCache.getInstance();

	private static String CACHE_KEY = "Authorization";

	private static int EXPIRE_TIME = 60 * 5;// 用户信息缓存时间，单位：秒

	@Autowired
	MicroServiceCaller microServiceCaller;

	@Autowired
	private ApiConfig config;

	@Autowired
	private PermissonConfig permissonConfig;

	@Override
	public UserRightViewModel getUserInfo() {
		String authorization = UserContextHolder.getAuthorization();
		if(StringUtils.isBlank(authorization)){
			throw new BussinessException(CodeMsg.API_UNAUTHORIZED,"未登录");
		}
		
		UserRightViewModel cacheValue = (UserRightViewModel) cache.getValue(CACHE_KEY + authorization);
		//如果缓存中有直接返回
		if (cacheValue != null&&cacheValue.getUserCode()!=null) {
			return cacheValue;
		} else {

			Map<String, String> heads = new HashMap<String, String>();
			heads.put("Authorization", authorization);
			String res = microServiceCaller.callApi(config.getGetUserInfo(), Scheme.HTTP, config.getGetUserInfoMethod(),
					null, heads, String.class);
			ResultInfoModel<UserRightViewModel> resultInfoModel = UserRightViewModel.convert(res);
			if (resultInfoModel != null && resultInfoModel.getCode() == 0) {
				UserRightViewModel userInfo = resultInfoModel.getResult();
				if (userInfo != null) {
					cache.putValue(CACHE_KEY + authorization, userInfo, EXPIRE_TIME);
				}
				return userInfo;

			} else {
				return null;
			}

		}

	}

	@Override
	public String getUserId() {
		UserRightViewModel userInfo = getUserInfo();
		if (userInfo != null) {
			return userInfo.getUserCode();
		}
		return null;
	}
	
	@Override
	public List<DepartmentModel> getDepartment() {
		String authorization = UserContextHolder.getAuthorization();
		Map<String,String> heads = new HashMap<String,String>();
		heads.put("Authorization", authorization);
		String res = microServiceCaller.callApi(config.getGetDepartment(), Scheme.HTTP, config.getGetDepartmentMethod(),null, heads, String.class);
		ResultInfoModel<List<DepartmentModel>> infoModel = DepartmentModel.convert(res);
		if(infoModel != null && infoModel.getCode() == 0){
			return infoModel.getResult();
		} else{
			throw ExceptionModel.convert(res);
		}
		//return ResultInfoModel.convertList(res, new DictModel());
	}

	@Override
	public List<DepartmentModel> getSomeDepartment(List<String> departmentIds) {
		String authorization = UserContextHolder.getAuthorization();
		Map<String,String> heads = new HashMap<String,String>();
		heads.put("Authorization", authorization);
		String res = microServiceCaller.callApi(config.getGetSameDepartment(), Scheme.HTTP, config.getGetSameDepartmentMethod(),departmentIds, heads, String.class);
		ResultInfoModel<List<DepartmentModel>> infoModel = DepartmentModel.convert(res);
		if(infoModel != null && infoModel.getCode() == 0){
			return infoModel.getResult();
		} else{
			throw ExceptionModel.convert(res);
		}
	}

    @Override
    public List<DepartmentModel> getSomeDepartment(Set<String> departmentIds) {
	    return getSomeDepartment(new ArrayList<String>(departmentIds));
    }

	@Override
	public PermissonDepartmentInfo getPermissonDepartmentInfo(String functionCode,String actionCode) {
		PermissonDepartmentInfo res = new PermissonDepartmentInfo();
		UserRightViewModel userInfo = UserContextHolder.getUserInfo();

		if(userInfo.getIsAdmin()){
			res.setFullPermisson(true);
		}else if(hasFA(userInfo.getPermissionList(),functionCode,actionCode)){
			res.setFullPermisson(true);
		}else{
			res.setFullPermisson(false);
			List<DepartmentModel> departmentList = getGetPermissonDepartmentByFACode(functionCode,actionCode);
			List<String> departmentIdList = Lists.newArrayList();
			if(!CollectionUtils.isEmpty(departmentList)){
				departmentList.forEach(d->{
					departmentIdList.add(d.getDepartmentId());
				});
			}
			res.setDepartmentIdList(departmentIdList);
		}
		return res;
	}

	private List<DepartmentModel> getGetPermissonDepartmentByFACode(String functionCode, String actionCode) {
		String authorization = UserContextHolder.getAuthorization();
		Map<String,String> heads = new HashMap<String,String>();
		heads.put("Authorization", authorization);
		Map<String,Object> params = Maps.newHashMap();
		params.put("functionCode",functionCode);
		params.put("actionCode",actionCode);
		String res = microServiceCaller.callApi(config.getGetPermissonDepartmentByFACode(), Scheme.HTTP, config.getGetPermissonDepartmentByFACodeMethod(),true,params, heads, String.class);
		ResultInfoModel<List<DepartmentModel>> infoModel = DepartmentModel.convert(res);
		if(infoModel != null && infoModel.getCode() == 0){
			return infoModel.getResult();
		} else{
			throw ExceptionModel.convert(res);
		}
	}

	@Override
	public PermissonDepartmentInfo getSpottingSearchPermissonDepartmentInfo() {
		return getPermissonDepartmentInfo(permissonConfig.getSpottingSearchFc(),permissonConfig.getSpottingSearchFullDeptAc());
	}

	@Override
	public PermissonDepartmentInfo getFrontdeviceSearchPermissonDepartmentInfo() {
		return getPermissonDepartmentInfo(permissonConfig.getFrontdeviceSearchFc(),permissonConfig.getFrontdeviceSearchFullDeptAc());
	}

	@Override
	public UserModel getSomeAccountByCode(String userCode) {
		List<UserModel> list = this.getSomeAccountByCode(Arrays.asList(userCode));
		if(!CollectionUtils.isEmpty(list)){
			return list.get(0);
		}else{
			return null;
		}
	}

	public List<UserModel> getSomeAccountByCode(List<String> userCodeList){

		String authorization = UserContextHolder.getAuthorization();
		Map<String,String> heads = new HashMap<String,String>();
		heads.put("Authorization", authorization);

		String res = microServiceCaller.callApi(config.getGetSomeAccountByCode(), Scheme.HTTP, config.getGetSomeAccountByCodeMethod(),userCodeList, heads, String.class);
		ResultInfoModel<List<UserModel>> infoModel = UserModel.convertList(res);
		if(infoModel != null && infoModel.getCode() == 0){
			return infoModel.getResult();
		} else{
			throw ExceptionModel.convert(res);
		}

	}

	@Override
	public List<String> queryChildDepartmentId(String departmentid) {
		String authorization = UserContextHolder.getAuthorization();
		Map<String,String> heads = new HashMap<String,String>();
		heads.put("Authorization", authorization);
		Map<String,Object> params = Maps.newHashMap();
		params.put("departmentId",departmentid);
		String res = microServiceCaller.callApi(config.getQueryChildDepartmentId(), Scheme.HTTP, config.getQueryChildDepartmentIdMethod(),true,params, heads, String.class);
		ResultInfoModel<List<String>> infoModel = DepartmentModel.convertLis(res);
		if(infoModel != null && infoModel.getCode() == 0){
			return infoModel.getResult();
		} else{
			throw ExceptionModel.convert(res);
		}
	}

	private boolean hasFA(List<PermissionDetailModel> permissionList,String functionCode,String actionCode) {
		if(!CollectionUtils.isEmpty(permissionList)){
			for (PermissionDetailModel p:permissionList){
				if(p.getFunctionCode().equals(functionCode)){
					List<String> actionCodeList = p.getActionCodeList();
					if(!CollectionUtils.isEmpty(actionCodeList)){
						for (String a:actionCodeList) {
							if(a.equals(actionCode)){
								return true;
							}
						}
					}
					break;
				}
			}
		}

		return false;
	}
}
